home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
lib
/
m
/
RCS
/
floor.c,v
< prev
next >
Wrap
Text File
|
1990-02-16
|
5KB
|
224 lines
head 1.3;
branch ;
access ;
symbols ;
locks ; strict;
comment @ * @;
1.3
date 90.02.16.12.52.35; author douglis; state Exp;
branches ;
next 1.2;
1.2
date 89.09.25.17.32.39; author rab; state Exp;
branches ;
next 1.1;
1.1
date 89.09.25.17.07.21; author rab; state Exp;
branches ;
next ;
desc
@@
1.3
log
@fixes for ds3100
@
text
@/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of California at Berkeley. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
* All recipients should regard themselves as participants in an ongoing
* research project and hence should feel obligated to report their
* experiences (good or bad) with these elementary function codes, using
* the sendbug(8) program, to the authors.
*/
#ifndef lint
static char sccsid[] = "@@(#)floor.c 5.3 (Berkeley) 5/21/88";
#endif /* not lint */
#if defined(vax)||defined(tahoe)
#ifdef vax
#define _0x(A,B) 0x/**/A/**/B
#else /* vax */
#define _0x(A,B) 0x/**/B/**/A
#endif /* vax */
static long Lx[] = {_0x(0000,5c00),_0x(0000,0000)}; /* 2**55 */
#define L *(double *) Lx
#else /* defined(vax)||defined(tahoe) */
#ifdef __STDC__
volatile static double L = 2 * 4503599627370496.0E0; /* 2**53 */
#else
static double L = 2 * 4503599627370496.0E0; /* 2**53 */
#endif
#endif /* defined(vax)||defined(tahoe) */
#ifdef ds3100
#define MAXLONG 2147483648.0E0
#endif
/*
* floor(x) := the largest integer no larger than x;
* ceil(x) := -floor(-x), for all real x.
*
* Note: Inexact will be signaled if x is not an integer, as is
* customary for IEEE 754. No other signal can be emitted.
*/
double
floor(x)
double x;
{
double y,ceil();
if (
#if !defined(vax)&&!defined(tahoe)
x != x || /* NaN */
#endif /* !defined(vax)&&!defined(tahoe) */
x >= L) /* already an even integer */
return x;
else if (x < (double)0)
return -ceil(-x);
/*
* This will ensure floor() is computed correctly at least for values of x
* within the range of long's.
* The algorithm used otherwise gives bogus results on ds3100.
* E.g.: floor(1.0) = 0.0, floor(-3.0) = -3.0, etc.
*/
#ifdef ds3100
else if ( x < MAXLONG )
return (long)x;
#endif
else { /* now 0 <= x < L */
y = L+x; /* destructive store must be forced */
y -= L; /* an integer, and |x-y| < 1 */
return x < y ? y-(double)1 : y;
}
}
double
ceil(x)
double x;
{
double y,floor();
if (
#if !defined(vax)&&!defined(tahoe)
x != x || /* NaN */
#endif /* !defined(vax)&&!defined(tahoe) */
x >= L) /* already an even integer */
return x;
else if (x < (double)0)
return -floor(-x);
#ifdef ds3100
else if ( x < MAXLONG )
return x == (long)x ? x : (long)x + 1.0;
#endif
else { /* now 0 <= x < L */
y = L+x; /* destructive store must be forced */
y -= L; /* an integer, and |x-y| < 1 */
return x > y ? y+(double)1 : y;
}
}
#ifndef national /* rint() is in ./NATIONAL/support.s */
/*
* algorithm for rint(x) in pseudo-pascal form ...
*
* real rint(x): real x;
* ... delivers integer nearest x in direction of prevailing rounding
* ... mode
* const L = (last consecutive integer)/2
* = 2**55; for VAX D
* = 2**53; for IEEE 754 Double
* real s,t;
* begin
* if x != x then return x; ... NaN
* if |x| >= L then return x; ... already an integer
* s := copysign(L,x);
* t := x + s; ... = (x+s) rounded to integer
* return t - s
* end;
*
* Note: Inexact will be signaled if x is not an integer, as is
* customary for IEEE 754. No other signal can be emitted.
*/
double
rint(x)
double x;
{
double s,t,one = 1.0,copysign();
#if !defined(vax)&&!defined(tahoe)
if (x != x) /* NaN */
return (x);
#endif /* !defined(vax)&&!defined(tahoe) */
if (copysign(x,one) >= L) /* already an integer */
return (x);
s = copysign(L,x);
t = x + s; /* x+s rounded to integer */
return (t - s);
}
#else /* !national */
/*
* The ds3100 defines national but doesn't have the auxiliary routine
* mentioned above.
*/
#ifdef ds3100
double
rint(x)
double x;
{
register double fx = floor(x);
if ( x - fx < 0.5 /* floor is the nearest int */ ||
x - fx == 0.5 && fx == 2.0 * floor(fx / 2.0)
/* floor is the nearest EVEN int */ )
return fx;
else
return fx + 1.0;
}
#endif /* ds3100 */
#endif /* not national */
@
1.2
log
@Added an extra bit to `L'. There are 52 bits of precision in
an IEEE 754 double, but there is also a hidden bit in normalized
numbers. So there is really 53 bits.
@
text
@d37 3
d62 10
d93 4
d141 20
@
1.1
log
@Initial revision
@
text
@d31 5
a35 1
static double L = 4503599627370496.0E0; /* 2**52 */
d96 1
a96 1
* = 2**52; for IEEE 754 Double
@